using System;
using System.Data;
using System.Windows.Forms;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using FireStarterModeller.UI.Relationship;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO.ClassDefinition;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using Microsoft.Practices.Unity;
using DataGridViewColumnSortMode=Habanero.Faces.Base.DataGridViewColumnSortMode;
using ReadOnlyDataSetProvider=Habanero.BO.ReadOnlyDataSetProvider;

namespace FireStarterModeller.UI
{
    public class DMRelationshipSelectorControl : UserControlWin, IFormControl, IBOParentChildrenSelector
    {
        private DMClass _class;
        public IControlFactory ControlFactory { get; private set; }
        public IGridControl GridControl { get; private set; }
//
//        public event EventHandler<BOEventArgs<DMRelationship>> RelationshipSelected;

        public DMRelationshipSelectorControl(IControlFactory controlFactory)
        {
            if (controlFactory == null)
                throw new HabaneroArgumentException
                    ("controlFactory", "Cannot create an 'DMRelationshipSelectorControl' if the control factory is null");
            ControlFactory = controlFactory;
            GridControl = controlFactory.CreateEditableGridControl();
            GridControl.Initialise(ClassDef.Get<DMRelationship>());


            foreach (IDataGridViewColumn column in GridControl.Grid.Columns)
            {
                column.SortMode = DataGridViewColumnSortMode.NotSortable;
            }
            this.GridControl.ConfirmDeletion = true;
            this.GridControl.CheckUserConfirmsDeletionDelegate = CheckUserConfirmsDeletionDelegate;

            GridControl.Buttons.AddButton
                ("ShowRelationshipCreator", "Add", (sender, e) => ShowRelationshipCreator());
//            if (GridControl.Buttons["Edit"] != null) GridControl.Buttons["Edit"].Visible = false;
//            if (GridControl.Buttons["Delete"] != null) GridControl.Buttons["Delete"].Visible = false;
            if (GridControl.Buttons["Add"] != null) GridControl.Buttons["Add"].Visible = true;
            if (GridControl.Buttons["Save"] != null)
            {
                //GridControl.Buttons["Save"].Width = 70;
                GridControl.Buttons["Save"].Visible = false;
            }
                
//            if (GridControl.Buttons["Cancel"] != null) GridControl.Buttons["Cancel"].Width = 70;
            GridControl.FilterControl.Visible = false;
            BorderLayoutManager mainLayoutManager = controlFactory.CreateBorderLayoutManager(this);
            mainLayoutManager.AddControl(GridControl, BorderLayoutManager.Position.Centre);
//  
            GridControl.BusinessObjectSelected +=
                (sender, e) => FireRelationshipSelected((DMRelationship) e.BusinessObject);
//
            this.Enabled = false;

        }

        private bool CheckUserConfirmsDeletionDelegate()
        {
            var relationship = this.SelectedBusinessObject as DMRelationship;
            if (relationship == null) return true;
            if (!CheckUserWantsToDelete()) return false;

            //You do not want to automatically delete relationship props
            // where there is a composite foreign key.
            if (!HasRelationshipProps(relationship) || HasCompositeRelationshipProps(relationship) )
            {
                return true;
            }
            if(relationship.OwningBOHasForeignKey) return true;
            DMRelationshipProperty relationshipProperty = relationship.RelationshipProperties[0];

            var result = MessageBox.Show
                               (FMResources.You_have_chosen_to_delete_the__ + relationship.RelationshipName + FMResources.Do_you_want_to_delete_the  
                                + FMResources.Foreign_Key_Property_QuestionMark, FMResources.DeleteQuestionMark, System.Windows.Forms.MessageBoxButtons.YesNo,
                                System.Windows.Forms.MessageBoxIcon.Exclamation);

            if (result == System.Windows.Forms.DialogResult.No) return true;

            var relationshipPropertyDeleter = new DMRelationshipPropertyDeleter(relationshipProperty);
            relationshipPropertyDeleter.Delete();
            
          return true;
        }

        private static bool HasCompositeRelationshipProps(IDMRelationship relationship)
        {
            return relationship.RelationshipProperties.Count > 1;
        }

        private static bool HasRelationshipProps(IDMRelationship relationship)
        {
            return relationship.RelationshipProperties.Count != 0;
        }

        /// <summary>
        /// Displays a message box to the user to check if they want to proceed with
        /// deleting the selected rows.
        /// </summary>
        /// <returns>Returns true if the user does want to delete</returns>
        private static bool CheckUserWantsToDelete()
        {
            return
                MessageBox.Show
                    (FMResources.Are_you_sure_you_want_to_delete_the_selected_row_s, FMResources.DeleteQuestionMark, System.Windows.Forms.MessageBoxButtons.YesNo,
                     System.Windows.Forms.MessageBoxIcon.Exclamation) == System.Windows.Forms.DialogResult.Yes;
        }

        private void ShowRelationshipCreator()
        {
            IUnityContainer container = new AutoResolvingUnityContainer();
//            container.RegisterType<DMRelationshipCreator, DMRelationshipCreator>();
            _createRelationshipWizardCntrller = new CreateRelationshipWizardController(container, this.Class);
//            _createRelationshipWizardCntrller.FireAssetTypeCreated +=
//                delegate(object sender, BOEventArgs<AssetType> e) { RefreshGrid(e.BusinessObject); };
            WizardFormWin wizardFrm = new WizardFormWin(_createRelationshipWizardCntrller, GlobalUIRegistry.ControlFactory)
                                          {
                                              Width = 800, Height = 650,
                                              WizardText = "Create Relationship Wizard"
                                          };
            wizardFrm.ShowDialog();
        }


        public DMClass Class
        {
            get { return _class; }
            set
            {
                _class = value;
                if (_class != null)
                {
                    this.Enabled = true;
                    GridControl.BusinessObjectCollection = _class.OwnerRelationships;
                }
                else
                {
                    this.Enabled = false;
                    GridControl.BusinessObjectCollection = null;
                }
            }
        }

        private void FireRelationshipSelected(DMRelationship dmRelationship)
        {
            if (this.BusinessObjectSelected != null)
            {
                this.BusinessObjectSelected(this, new BOEventArgs(dmRelationship));
            }
        }


        private void SetupRelatedClassColumn()
        {
            Habanero.BO.BusinessObjectCollection<DMClass> classes = new Habanero.BO.BusinessObjectCollection<DMClass>();
            if (this.Solution != null)
            {
                classes = this.Solution.AllClasses;
            }

            SetupColumnLookupWithClasses(classes, "ReverseRelationship.ClassID");
        }

        private void SetupColumnLookupWithClasses
            (Habanero.BO.BusinessObjectCollection<DMClass> classes, string columnName)
        {
            ReadOnlyDataSetProvider readOnlyDataSetProvider = new ReadOnlyDataSetProvider(classes);
            IUIGrid uiGrid = ClassDef.Get<DMClass>().GetUIDef("ComboLookup").UIGrid;
            DataTable dataTable = readOnlyDataSetProvider.GetDataTable(uiGrid);
            IDataGridViewComboBoxColumn column = (IDataGridViewComboBoxColumn) this.GridControl.Grid.Columns[columnName];
            column.DataSource = dataTable;
            column.DisplayMember = "ClassNameBO";
            column.ValueMember = "ClassID";
        }

        ///<summary>
        ///
        ///            Sets the form to control
        ///            
        ///</summary>
        ///
        ///<param name="form">The form to control</param>
        public void SetForm(IFormHabanero form)
        {
        }

        #region Implement IBOParentChildrenSelector

        ///<summary>
        ///
        ///            Gets or sets the parent business object being represented (in this case the <see cref="DMClass"/>
        ///            
        ///</summary>
        ///
        public IBusinessObject BusinessObject
        {
            get { return Class; }
            set { Class = (DMClass) value; }
        }

        #endregion

        #region Implements IBOColSelector

        public event EventHandler<BOEventArgs> BusinessObjectSelected;

        public void Clear()
        {
            this.GridControl.Clear();
        }

        public IBusinessObject GetBusinessObjectAtRow(int row)
        {
            return this.GridControl.GetBusinessObjectAtRow(row);
        }

        public IBusinessObjectCollection BusinessObjectCollection
        {
            get { return this.GridControl.BusinessObjectCollection; }
            set { this.GridControl.BusinessObjectCollection = value; }
        }

        public IBusinessObject SelectedBusinessObject
        {
            get { return this.GridControl.SelectedBusinessObject; }
            set { this.GridControl.SelectedBusinessObject = value; }
        }

        public int NoOfItems
        {
            get { return this.GridControl.NoOfItems; }
        }

        /// <summary>
        ///             Gets and sets whether this selector autoselects the first item or not when a new collection is set.
        /// </summary>
        public bool AutoSelectFirstItem { get; set; }

        private DMSolution _solution;
        private CreateRelationshipWizardController _createRelationshipWizardCntrller;

        /// <summary>
        /// Gets and sets the Solution used to load the RelatedClasses Shown in the combobox selector of this control
        /// </summary>
        public DMSolution Solution
        {
            get { return _solution; }
            set
            {
                _solution = value;
                SetupRelatedClassColumn();
            }
        }

        #endregion
    }
}